<html>
<head><meta charset="utf-8"><title>Taking mutable references of items from slice · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html">Taking mutable references of items from slice</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="210768923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210768923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210768923">(Sep 21 2020 at 16:54)</a>:</h4>
<p>Hello, i want to ask a question about borrowing items from a slice. Imagine i have a <code>&amp;'a mut [T]</code> which has <code>N</code> items. I want to borrow all the elements at the same time, but in random order. Effectively I'm split borrowing the slice. I will do bookkeeping by storing all borrowed indexes inside a btreeset and reject any indexes that occured more than once. Is there anything i need to specially pay attention to when implementing this if i want it be accepted by the stacked borrows model?</p>



<a name="210772820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210772820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210772820">(Sep 21 2020 at 17:23)</a>:</h4>
<p>This sounds like a slight refactoring around a <code>Vec&lt;RefCell&lt;&amp;mut T&gt;&gt;</code></p>



<a name="210773079"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210773079" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210773079">(Sep 21 2020 at 17:25)</a>:</h4>
<p>As long as you actually don't access a <code>&amp;mut T</code> twice at once I think there are no problems here</p>



<a name="210774023"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210774023" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210774023">(Sep 21 2020 at 17:32)</a>:</h4>
<p>Sure! I can call <code>iter_mut()</code> and collect up all the mutable references. This will achieve full "split borrowing". It's just that this will come with O(n) space complexity, because i have to prepare all references ahead of time for them to "take away".</p>



<a name="210776437"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210776437" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210776437">(Sep 21 2020 at 17:52)</a>:</h4>
<p>I'm not confident here, but I suspect you might need to get all the <code>&amp;mut T</code>s via a raw pointer -- if you go back to the <code>&amp;mut [T]</code> to get another one, it's non-obvious to me whether using that again invalidates the others, since IIRC it "claims" the whole slice again.</p>



<a name="210776474"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210776474" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210776474">(Sep 21 2020 at 17:52)</a>:</h4>
<p><del>mumble mumble provenance</del></p>



<a name="210777539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210777539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210777539">(Sep 21 2020 at 18:00)</a>:</h4>
<p>(I would also note that a BTreeSet seems really awkward compared to pre-allocating a bitset)</p>



<a name="210777623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210777623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210777623">(Sep 21 2020 at 18:00)</a>:</h4>
<p>I'm pretty sure <span class="user-mention" data-user-id="125270">@scottmcm</span> is right that you need to, once, cast the whole slice to a pointer to T (note: critical that it be the whole slice) and then offset from that to each element</p>



<a name="210777779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210777779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210777779">(Sep 21 2020 at 18:01)</a>:</h4>
<p>Agreed with <span class="user-mention" data-user-id="125270">@scottmcm</span>, I'd propably use the following helper as the intermediate object to obtain the references without violating provenance:</p>
<div class="codehilite"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">use</span><span class="w"> </span><span class="n">safety_boundary</span>::<span class="n">SliceMut</span><span class="p">;</span><span class="w"></span>
<span class="k">mod</span> <span class="nn">safety_boundary</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">use</span><span class="w"> </span>::<span class="n">core</span>::<span class="p">{</span><span class="n">marker</span>::<span class="n">PhantomData</span><span class="p">,</span><span class="w"> </span><span class="n">ptr</span><span class="p">};</span><span class="w"></span>

<span class="w">    </span><span class="k">pub</span><span class="w"></span>
<span class="w">    </span><span class="k">struct</span> <span class="nc">SliceMut</span><span class="o">&lt;</span><span class="na">&#39;lt</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">ptr</span>: <span class="nc">ptr</span>::<span class="n">NonNull</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">len</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="n">_lifetime</span>: <span class="nc">PhantomData</span><span class="o">&lt;&amp;</span><span class="na">&#39;lt</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">impl</span><span class="o">&lt;</span><span class="na">&#39;lt</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">SliceMut</span><span class="o">&lt;</span><span class="na">&#39;lt</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">pub</span><span class="w"></span>
<span class="w">        </span><span class="k">fn</span> <span class="nf">new</span><span class="w"> </span><span class="p">(</span><span class="n">slice</span>: <span class="kp">&amp;</span><span class="na">&#39;lt</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="n">T</span><span class="p">])</span><span class="w"></span>
<span class="w">          </span>-&gt; <span class="nc">Self</span><span class="w"></span>
<span class="w">        </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="bp">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">len</span>: <span class="nc">slice</span><span class="p">.</span><span class="n">len</span><span class="p">(),</span><span class="w"></span>
<span class="w">                </span><span class="n">ptr</span>: <span class="nc">ptr</span>::<span class="n">NonNull</span>::<span class="n">new</span><span class="p">(</span><span class="n">slice</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">()).</span><span class="n">unwrap</span><span class="p">(),</span><span class="w"></span>
<span class="w">                </span><span class="n">_lifetime</span>: <span class="nc">PhantomData</span><span class="p">,</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>

<span class="w">        </span><span class="k">pub</span><span class="w"></span>
<span class="w">        </span><span class="k">unsafe</span><span class="w"> </span><span class="c1">// Safety: must not be called with the same `idx` multiple times.</span>
<span class="w">        </span><span class="k">fn</span> <span class="nf">at</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span>: <span class="kp">&amp;</span><span class="nb">&#39;_</span><span class="w"> </span><span class="bp">Self</span><span class="p">,</span><span class="w"> </span><span class="n">idx</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"></span>
<span class="w">          </span>-&gt; <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="na">&#39;lt</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"></span>
<span class="w">        </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">idx</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">len</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="nb">Some</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">ptr</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">().</span><span class="n">add</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="nb">None</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="210827239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210827239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210827239">(Sep 22 2020 at 04:31)</a>:</h4>
<p>Thanks!</p>



<a name="210936473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210936473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210936473">(Sep 22 2020 at 21:57)</a>:</h4>
<p>Why not just use <code>Vec&lt;Cell&lt;T&gt;&gt;</code>? <br>
You can easily then get references to the inner part, this sounds like a better safer solution to me,<br>
unless you can't change the <code>&amp;'a mut [T]</code> part</p>



<a name="210937212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210937212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210937212">(Sep 22 2020 at 22:04)</a>:</h4>
<p><span class="user-mention" data-user-id="249222">@Elichai Turkel</span> that's also an interesting idea: from a <code>&amp;mut [T]</code> you can <a href="https://doc.rust-lang.org/core/cell/struct.Cell.html#method.as_slice_of_cells">construct a <code>&amp;[Cell&lt;T&gt;]</code></a>, which is an <code>unsafe</code>-free solution, and does not even need the set property (although it is still _advisable_)</p>



<a name="210937332"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210937332" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210937332">(Sep 22 2020 at 22:05)</a>:</h4>
<p>That looks like it's from <code>Cell&lt;[T]&gt;</code>?</p>



<a name="210937502"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210937502" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210937502">(Sep 22 2020 at 22:06)</a>:</h4>
<p>Oh, so you call <code>Cell::from_mut(&amp;mut [T]).as_slice_of_cells()</code> cool!</p>



<a name="210952723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210952723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210952723">(Sep 23 2020 at 02:11)</a>:</h4>
<p>Example at <a href="https://stackoverflow.com/a/62564887/155423">Simultaneous mutable access to arbitrary indices of a large vector that are guaranteed to be disjoint</a></p>



<a name="210952786"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/210952786" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#210952786">(Sep 23 2020 at 02:12)</a>:</h4>
<p>You can see my <code>BTreeSet</code> version there as well.</p>



<a name="211014139"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/211014139" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#211014139">(Sep 23 2020 at 14:49)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116155">Jake Goulding</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice/near/210952723">said</a>:</p>
<blockquote>
<p>Example at <a href="https://stackoverflow.com/a/62564887/155423">Simultaneous mutable access to arbitrary indices of a large vector that are guaranteed to be disjoint</a></p>
<p>A <code>&amp;[Cell&lt;T&gt;]</code> is almost like a <code>&amp;[&amp;mut T]</code>,</p>
</blockquote>
<p>I'm not super fond of that comparison, since the right hand-side has an extra indirection; what about:</p>
<blockquote>
<p>A <code>&amp;[Cell&lt;T&gt;]</code> is a <code>&amp;[mut T]</code>, if that were possible to write: a <em>shared</em> reference to a slice of <em>mutable</em> elements.</p>
</blockquote>
<p>You could then even add something along the lines of:</p>
<blockquote>
<p>This is safe since the <code>Cell</code> type is a wrapper type with a limited API that makes mutation within a single thread be always safe, and is also a type that Rust knows is not thread-safe (not <code>Sync</code>)</p>
</blockquote>
<hr>
<p>But in all cases, let's avoid adding an indirection where there isn't one, since some beginners mix up all these "smart pointers" <code>Rc, Cell, RefCell, ...</code> <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span></p>



<a name="211018434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking%20mutable%20references%20of%20items%20from%20slice/near/211018434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Taking.20mutable.20references.20of.20items.20from.20slice.html#211018434">(Sep 23 2020 at 15:19)</a>:</h4>
<p><span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> I passed that along to the author and <a href="https://stackoverflow.com/posts/62564887/revisions">they made changes</a>. Thoughts?</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>